﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace BinarySplitter
{
    class BinarySplitter
    {
        public static void CreateBinaryFile(string filename, byte[] informationToWrite)
        {
            if (File.Exists(filename))
            {
                File.Delete(filename);
            }

            FileStream outputFile = File.Create(filename);

            using (outputFile)
            {
                outputFile.Write(informationToWrite, 0, informationToWrite.Length);
            }
        }

        public static void SplitBinaryFile(string filename)
        {
            FileStream inputFile = File.Open(filename, FileMode.Open);
            const int BufferSize = 4096;
            using (inputFile)
            {
                long bytesInFile = inputFile.Length;
                long halfBytes = bytesInFile / 2;

                byte[] buffer = new byte[BufferSize];
                long currentBytesWrittenToFirstFile = 0;
                bool isWritingToFirstFile = true;
                FileStream halfFile = File.Open("firstPart_" + filename, FileMode.OpenOrCreate);
                using (halfFile)
                {

                    int bytesRead = inputFile.Read(buffer, 0, buffer.Length);
                    while (bytesRead != 0)
                    {
                        long offset = 0;
                        if (isWritingToFirstFile)
                        {
                            long bytesToWrite = halfBytes - currentBytesWrittenToFirstFile;

                            if (bytesToWrite > 0)
                            {
                                halfFile.Write(buffer, 0, (int)(bytesRead - bytesToWrite));
                                offset = bytesRead - bytesToWrite;
                            }

                            if (bytesRead > bytesToWrite)
                            {
                                isWritingToFirstFile = false;
                                currentBytesWrittenToFirstFile = 0;
                                halfFile = File.Open("secondPart_" + filename, FileMode.OpenOrCreate);
                            }
                        }

                        if (isWritingToFirstFile == false)
                        {
                            halfFile.Write(buffer, (int)offset, (int)(bytesRead - offset));
                            offset = 0;
                        }

                        bytesRead = inputFile.Read(buffer, 0, buffer.Length);
                    }
                }
                halfFile.Close();
                inputFile.Close();
            }
        }

        public static void UniteTwoFiles(string firstFilename, string secondFilename, string resultFile)
        {
            FileStream input = File.Open(firstFilename, FileMode.Open);
            using (input)
            {
                FileStream output = File.Open(resultFile, FileMode.OpenOrCreate);
                using (output)
                {
                    WriteToFile(input, output);
                    input = File.Open(secondFilename, FileMode.Open);
                    WriteToFile(input, output);
                    input.Close();
                }
                output.Close();
            }
        }

        public static void WriteToFile(FileStream input, FileStream output)
        {
            byte[] buffer = new byte[4096];
            int bytesRead = input.Read(buffer, 0, buffer.Length);
            while (bytesRead > 0)
            {
                output.Write(buffer, 0, bytesRead);
                bytesRead = input.Read(buffer, 0, buffer.Length);
            }
        }
    }
}
